﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Windows.Forms;

namespace OCR
{
    public partial class ImageView : Form
    {
        public event OkHandler OnOkClick;

        private string value;
        /// <summary>
        /// 识别结果
        /// </summary>
        public string Value
        {
            get { return this.value; }
            set { this.value = value; }
        }
        private string imagePath;

        public string ImagePath
        {
            get { return imagePath; }
            set { imagePath = value; }
        }

        private Bitmap curBitmap;


        Point start; //画框的起始点

        bool blnDraw;//判断是否绘制<br>
        bool isMove;
        Rectangle rect;
        Rectangle newRect;
        private int count;

        public int Count
        {
            get { return count; }
            set { count = value; }
        }

        private int rowIndex;
        public int RowIndex
        {
            get { return rowIndex; }
            set { rowIndex = value; }
        }
        //当前显示图片与原始图片缩放比例
        private double rate = 1;
        //原始图片左上角坐标
        private double original_x, original_y;
        public ImageView(string imagePath, int rowIndex, int count)
        {
            InitializeComponent();
            this.imagePath = imagePath;
            this.rowIndex = rowIndex;
            this.count = count;
        }

        private void AdjustSourceImageView_Load(object sender, EventArgs e)
        {
            this.ShowImage();
        }
        public void ShowImage()
        {
            Bitmap image = new Bitmap(this.imagePath);
            this.pbSource.Image = image;
            //原始图片比例
            this.rate = (float)image.Size.Width / (float)image.Size.Height;
            this.pbSource.Refresh();
        }


        private void pbSource_MouseDown(object sender, MouseEventArgs e)
        {
            // 按下鼠标右键，记录鼠标按下的位置
            start = e.Location;
            if (e.Button == MouseButtons.Left)
            {
                PropertyInfo rectangleProperty = this.pbSource.GetType().GetProperty("ImageRectangle", BindingFlags.Instance | BindingFlags.NonPublic);
                Rectangle rectangle = (Rectangle)rectangleProperty.GetValue(this.pbSource, null);
                //当前缩放比例
                rate = (double)rectangle.Height / (double)this.pbSource.Image.Height;
                //左边空白
                int black_left_width = (rectangle.Width == this.pbSource.Width) ? 0 : (this.pbSource.Width - rectangle.Width) / 2;
                //上边空白
                int black_top_height = (rectangle.Height == this.pbSource.Height) ? 0 : (this.pbSource.Height - rectangle.Height) / 2;
                //缩略图坐标
                int zoom_x = e.X - black_left_width;
                int zoom_y = e.Y - black_top_height;
                //原始图坐标
                original_x = (double)zoom_x / rate;
                original_y = (double)zoom_y / rate;

                Invalidate();
                blnDraw = true;
            }
        }

        private void pbSource_MouseMove(object sender, MouseEventArgs e)
        {
            if (blnDraw)
            {
                if (e.Button != MouseButtons.Left)//判断是否按下左键
                    return;
                Point tempEndPoint = e.Location; //记录框的位置和大小
                rect.Location = new Point(
                Math.Min(start.X, tempEndPoint.X),
                Math.Min(start.Y, tempEndPoint.Y));
                rect.Size = new Size(
                Math.Abs(start.X - tempEndPoint.X),
                Math.Abs(start.Y - tempEndPoint.Y));
                this.pbSource.Invalidate();
            }
          
        }

        private void pbSource_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                blnDraw = false; //结束绘制
                newRect = new Rectangle();
                newRect.X = Convert.ToInt32(original_x);
                newRect.Y = Convert.ToInt32(original_y);
                newRect.Width = Convert.ToInt32(rect.Width / rate);
                newRect.Height = Convert.ToInt32(rect.Height / rate);
                //截图并处理图片
                if (this.newRect.Width * this.newRect.Height > 100)
                {
                    this.pbResult.Image = BitmapHelper.CutProcessImage((Bitmap)this.pbSource.Image, newRect, BinarizationMethods.Otsu, this.ckbNoiseClear.Checked);
                    this.pbResult.Refresh();
                    this.Recognition();
                }
            }
        }

        private void pbSource_Paint(object sender, PaintEventArgs e)
        {
            if (blnDraw)
            {
                if (this.pbSource.Image != null)
                {
                    if (rect != null && rect.Width > 0 && rect.Height > 0)
                    {
                        e.Graphics.DrawRectangle(new Pen(Color.Red, 2), rect);//重新绘制颜色为红色
                    }
                }
            }
        }
        /// <summary>
        /// 字符识别
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btNum_Click(object sender, EventArgs e)
        {

            this.value = OCR.CharRecognition((Bitmap)this.pbResult.Image, OCR.FontFolderPath, "eng", "0123456789");

        }
        /// <summary>
        /// 条形码识别
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btBarCode_Click(object sender, EventArgs e)
        {
            this.value = OCR.BarCodeRecognition((Bitmap)this.pbResult.Image);
            if (this.OnOkClick != null)
            {
                OkEventArgs arg = new OkEventArgs();
                arg.RowIndex = this.rowIndex;
                arg.Value = this.value;
                this.OnOkClick(this, arg);
            }
        }
        private void ckbNoiseClear_CheckedChanged(object sender, EventArgs e)
        {
            this.pbResult.Image = BitmapHelper.CutProcessImage((Bitmap)this.pbSource.Image, newRect, BinarizationMethods.Otsu, this.ckbNoiseClear.Checked); ;
            this.pbResult.Refresh();
        }

        private void btOk_Click(object sender, EventArgs e)
        {
            if (!string.IsNullOrEmpty(this.tbResult.Text))
            {
                if (this.tbResult.Text.Trim().Length == this.count)
                {
                    if (this.OnOkClick != null)
                    {
                        OkEventArgs arg = new OkEventArgs();
                        arg.RowIndex = this.rowIndex;
                        arg.Value = this.tbResult.Text;
                        this.OnOkClick(this, arg);
                    }
                }
                else
                {
                    MessageBox.Show("位数不对！");
                }
            }
            else
            {
                MessageBox.Show("识别结果不正确，请重新框选识别区域！");
            }
        }

        private void rbBarCode_CheckedChanged(object sender, EventArgs e)
        {
            this.Recognition();

        }
        private void Recognition()
        {
            if (this.pbResult.Image != null)
            {
                if (this.rbNum.Checked)
                {
                    this.value = OCR.CharRecognition((Bitmap)this.pbResult.Image, OCR.FontFolderPath, "eng", "0123456789");
                }
                else
                {
                    this.value = OCR.BarCodeRecognition((Bitmap)this.pbResult.Image);
                }
                this.tbResult.Text = this.value;
                this.lbCount.Text = this.value.Length.ToString() + "位";
            }
        }
        private void rbNum_CheckedChanged(object sender, EventArgs e)
        {
            this.Recognition();
        }

        private void ImageView_FormClosing(object sender, FormClosingEventArgs e)
        {
            e.Cancel = true;
            this.Visible = false;
        }
    }

    public delegate void OkHandler(object sender, OkEventArgs e);

    public class OkEventArgs : EventArgs
    {
        public OkEventArgs()
        {

        }

        //行
        public int RowIndex;
        //值
        public string Value;
    }
}
